🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / androidApp / src / testFdroid / kotlin / org / meshtastic / app / map / KmlImportTest.kt
Displaying Raw • Download
androidApp/src/testFdroid/kotlin/org/meshtastic/app/map/KmlImportTest.kt renovate/fastlane-2.x-lockfile (056eed64) Text, 4.14 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.app.map
Tff7b72import T7ee787org.junit.Test
Tff7b72import T7ee787org.junit.runner.RunWith
Tff7b72import T7ee787org.robolectric.RobolectricTestRunner
Tff7b72import T7ee787java.io.BufferedInputStream
Tff7b72import T7ee787java.io.ByteArrayInputStream
Tff7b72import T7ee787java.io.ByteArrayOutputStream
Tff7b72import T7ee787java.util.Locale
Tff7b72import T7ee787java.util.zip.ZipEntry
Tff7b72import T7ee787java.util.zip.ZipOutputStream
Tff7b72import T7ee787kotlin.test.assertContains
Tff7b72import T7ee787kotlin.test.assertNotNull
Tff7b72import T7ee787kotlin.test.assertTrue
T8b949e/**
* What the Android side of KML import still owns: recognising a KMZ and pulling the KML out of it.
*
* The converter itself is common code and tested in `feature/map`. These stay here because a zip archive and the JVM
* default locale are both platform concerns — the locale case in particular guards the formatting that once emitted
* `0,498` into the JSON and made every import silently draw nothing.
*/
Tf0883e@RunWithTb4b4b4(Te6edf3RobolectricTestRunnerTff7b72::Te6edf3classTb4b4b4)
Tff7b72class T56d364KmlImportTest Tb4b4b4{
Tff7b72private Tff7b72fun Td2a8ffconvertTb4b4b4(Te6edf3kmlTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Tffa657String? Tff7b72=
Te6edf3convertKmlSourceTb4b4b4(Te6edf3BufferedInputStreamTb4b4b4(Te6edf3ByteArrayInputStreamTb4b4b4(Te6edf3kmlTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)Tff7b72?.Te6edf3geoJson
Tff7b72private Tff7b72fun Td2a8ffkmzTb4b4b4(Te6edf3kmlTb4b4b4: Tffa657StringTb4b4b4, Te6edf3entryNameTb4b4b4: Tffa657String Tff7b72= Ta5d6ff"Ta5d6ffdoc.kmlTa5d6ff"Tb4b4b4)Tb4b4b4: Te6edf3ByteArray Tb4b4b4{
Tff7b72val Te6edf3bytes Tff7b72= Te6edf3ByteArrayOutputStreamTb4b4b4(Tb4b4b4)
Te6edf3ZipOutputStreamTb4b4b4(Te6edf3bytesTb4b4b4)Tb4b4b4.Te6edf3use Tb4b4b4{ Te6edf3zip Tff7b72-Tff7b72>
Te6edf3zipTb4b4b4.Te6edf3putNextEntryTb4b4b4(Te6edf3ZipEntryTb4b4b4(Te6edf3entryNameTb4b4b4)Tb4b4b4)
Te6edf3zipTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3kmlTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3zipTb4b4b4.Te6edf3closeEntryTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72return Te6edf3bytesTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`a kmz is unzipped and read`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3archive Tff7b72= Te6edf3kmzTb4b4b4(Ta5d6ff"Ta5d6ff<kml><Placemark><Point><coordinates>-107.6,34.1</coordinates></Point></Placemark></kml>Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3result Tff7b72= Te6edf3assertNotNullTb4b4b4(Te6edf3convertKmlSourceTb4b4b4(Te6edf3BufferedInputStreamTb4b4b4(Te6edf3ByteArrayInputStreamTb4b4b4(Te6edf3archiveTb4b4b4)Tb4b4b4)Tb4b4b4)Tff7b72?.Te6edf3geoJsonTb4b4b4)
Te6edf3assertContainsTb4b4b4(Te6edf3resultTb4b4b4, Ta5d6ff"""Ta5d6ff"Ta5d6ffcoordinatesTa5d6ff"Ta5d6ff:[-107.6,34.1]Ta5d6ff"""Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`a kmz whose kml is not named doc is still found`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3archive Tff7b72=
Te6edf3kmzTb4b4b4(
Ta5d6ff"Ta5d6ff<kml><Placemark><Point><coordinates>1,2</coordinates></Point></Placemark></kml>Ta5d6ff"Tb4b4b4,
Te6edf3entryName Tff7b72= Ta5d6ff"Ta5d6fffiles/export.kmlTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3assertNotNullTb4b4b4(Te6edf3convertKmlSourceTb4b4b4(Te6edf3BufferedInputStreamTb4b4b4(Te6edf3ByteArrayInputStreamTb4b4b4(Te6edf3archiveTb4b4b4)Tb4b4b4)Tb4b4b4)Tff7b72?.Te6edf3geoJsonTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`a comma-decimal locale still emits valid json`Tb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// `%f` follows the device locale, so on a German phone the default would write 0,498 — invalid JSON, and
T8b949e// MapLibre rejects the whole file, so every KML import would silently draw nothing.
Tff7b72val Te6edf3original Tff7b72= Te6edf3LocaleTb4b4b4.Te6edf3getDefaultTb4b4b4(Tb4b4b4)
Tff7b72try Tb4b4b4{
Te6edf3LocaleTb4b4b4.Te6edf3setDefaultTb4b4b4(Te6edf3LocaleTb4b4b4.Te6edf3GERMANYTb4b4b4)
Tff7b72val Te6edf3result Tff7b72=
Te6edf3assertNotNullTb4b4b4(
Te6edf3convertTb4b4b4(
Ta5d6ff"""
Ta5d6ff <kml><Document>
<Style id=Ta5d6ff"Ta5d6ffzoneTa5d6ff"Ta5d6ff><PolyStyle><color>7f00ff00</color></PolyStyle></Style>
<Placemark><styleUrl>#zone</styleUrl><Polygon><outerBoundaryIs><LinearRing>
<coordinates>0,0 1,0 1,1 0,0</coordinates>
</LinearRing></outerBoundaryIs></Polygon></Placemark>
</Document></kml>
Ta5d6ff"""Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
T8b949e// The whole point: a dot, not a comma, in the property this locale would have written as 0,498.
Te6edf3assertContainsTb4b4b4(Te6edf3resultTb4b4b4, Ta5d6ff"""Ta5d6ff"Ta5d6fffill-opacityTa5d6ff"Ta5d6ff:0.498Ta5d6ff"""Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Ta5d6ff"""Ta5d6ff"Ta5d6fffill-opacityTa5d6ff"Ta5d6ff:0,Ta5d6ff""" Tff7b72!in Te6edf3resultTb4b4b4, Te6edf3resultTb4b4b4)
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3LocaleTb4b4b4.Te6edf3setDefaultTb4b4b4(Te6edf3originalTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.2 - Generated in 0.05s